package cn.yuanqiao.archive.sealmanage.service.impl;

import cn.yuanqiao.archive.appManager.service.ITenantSysConfigService;
import cn.yuanqiao.archive.chengguojieshou.mapper.YqdaarticulatedMapper;
import cn.yuanqiao.archive.sealmanage.PdfUtil;
import cn.yuanqiao.archive.sealmanage.domain.Cell;
import cn.yuanqiao.archive.sealmanage.domain.SealManage;
import cn.yuanqiao.archive.sealmanage.domain.Table;
import cn.yuanqiao.archive.sealmanage.mapper.SealmanageMapper;
import cn.yuanqiao.archive.sealmanage.service.ISealmanageService;
import cn.yuanqiao.common.exception.ServiceException;
import cn.yuanqiao.common.utils.DateUtils;
import cn.yuanqiao.common.utils.StringUtils;
import cn.yuanqiao.common.utils.SecurityUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itextpdf.text.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.*;


/**
 * 归档章管理Service业务层处理
 *
 * @author yuanqiao
 * @date 2023-10-11
 */
@Service
public class SealmanageServiceImpl implements ISealmanageService
{
    @Autowired
    private SealmanageMapper SealmanageMapper;
    @Autowired
    private ITenantSysConfigService sysConfigService;
    @Autowired
    private YqdaarticulatedMapper yqdaarticulatedMapper;

    private static final Logger logger = LoggerFactory.getLogger(SealmanageServiceImpl.class);

    /**
     * 查询归档章管理
     *
     * @param ID 归档章管理主键
     * @return 归档章管理
     */
    @Override
    public SealManage selectSealmanageByID(String ID)
    {
        SealManage sealManage = new SealManage();
        return SealmanageMapper.selectSealmanageByID(ID,sealManage.getTableName());
    }

    @Override
    public String getImagePath(Long id, String list) {
        SealManage sealManage = SealmanageMapper.selectSealmanageByID(id.toString(), new SealManage().getTableName());
        List<Map<String,Object>> list2 = new ArrayList<>();
        if(!"null".equals(list)){
            JSONArray jsonArray = JSONArray.parseArray(list);
            for(int i=0;i<jsonArray.size();i++){
                JSONObject o = (JSONObject)jsonArray.get(i);
                try {
                    Map<String,Object> map = new ObjectMapper().readValue(o.toString(), Map.class);
                    list2.add(map);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            }
        }
        String imagePath = getImagePath(sealManage, list2);
        return imagePath;
    }

    /**
     * 查询归档章管理列表
     *
     * @param Sealmanage 归档章管理
     * @return 归档章管理
     */
    @Override
    public List<SealManage> selectSealmanageList(SealManage Sealmanage)
    {
        return SealmanageMapper.selectSealmanageList(Sealmanage);
    }

    public String getImagePath(SealManage Sealmanage,Object obj){
        String isSave = "";
        List<Map<String, Object>> list = null;
        if(obj instanceof String){
            isSave = (String)obj;
        }
        if(obj instanceof List){
            list = (List<Map<String, Object>>)obj;
        }
        JSONArray jsonArray = Sealmanage.getTableStyleJson();
        if(jsonArray==null){
            jsonArray = JSONArray.parseArray(Sealmanage.getTableStyle());

        }
        String color1 = Sealmanage.getColor();
        String align = Sealmanage.getAlign();
        Integer fontBold = Sealmanage.getFontBold();
        String font1 = Sealmanage.getFont();
        Integer fontSize1 = Sealmanage.getFontSize();


        /**  https://blog.csdn.net/xuxiaoyinliu/article/details/125754032
         * type: 1 固定值 2动态值   belongColumn 从属单元格  belongColumn用于复杂表头处理，指的是该单元格的父级单元格所在的列 单元格宽度,对于有从属单元格的，其宽度由从属单元格决定
         * [{"row":1,"column":1,"type":1,"value":全宗号,"belongColumn":0,"width",100,"height":30},
         * {"row":2,"column":1,"type":1,"value":"年度","belongColumn":1,"width",100,"height":30},
         * {"row":2,"column":2,"type":2,"value":"ND","name":"[年度]","belongColumn":1,"width",100,"height":30}]
         */
        List<Cell> headCells = new ArrayList<>();
        //颜色
        String colors = color1.replaceAll("rgb\\(", "").replaceAll("\\)", "");
        String[] colorsArr = colors.split(",");
        Color color = new Color(Integer.valueOf(colorsArr[0].trim()),Integer.valueOf(colorsArr[1].trim()),Integer.valueOf(colorsArr[2].trim()));
        //Color color = Color.blue;   //颜色
        String contentAlign = "right";   //文字位置
        if(StringUtils.isNotEmpty(align)) contentAlign = align;
        int fontbold = 10;  //边框粗细
        if(null!=fontBold) fontbold = fontBold;
        String font = "仿宋";  //字体
        if(StringUtils.isNotEmpty(font1)) font = font1;
        int fontSize = 15;   //字号
        if(null!=fontSize1) fontSize = fontSize1;
        //总体高度 所以行高相加
        int rowHeight = 30;   //行高
        //总体宽度 所以行宽相加
        //单元格宽度,对于有从属单元格的，其宽度由从属单元格决定
        int rowWidth = 100;
        for(int i = 0;i<jsonArray.size();i++){
            JSONArray ja =new JSONArray();
            if(jsonArray.get(i) instanceof JSONArray){
                ja=(JSONArray)jsonArray.get(i);
            }else if(jsonArray.get(i) instanceof JSONObject){
                ja.add(jsonArray.get(i));
            }else if(jsonArray.get(i) instanceof List){
                ArrayList arrayList = (ArrayList) jsonArray.get(i);
                for(int l=0;l<arrayList.size();l++){
                    ja.add(arrayList.get(l));
                }
            }
            for(int j=0;j<ja.size();j++){
                Object o1 = ja.get(j);
                Map<String, Object> jb = new HashMap<>();
                if(o1 instanceof LinkedHashMap){
                    LinkedHashMap<String,Object> lm = (LinkedHashMap) ja.get(j);
                    Set<Map.Entry<String, Object>> entries = lm.entrySet();
                    Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
                    while (iterator.hasNext()){
                        Map.Entry<String, Object> next = iterator.next();
                        jb.put(next.getKey(),next.getValue());
                    }
                }
                if(o1 instanceof JSONObject){
                    JSONObject jsonObject = (JSONObject) ja.get(j);
                    Set<Map.Entry<String, Object>> entries = jsonObject.entrySet();
                    Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
                    while (iterator.hasNext()){
                        Map.Entry<String, Object> next = iterator.next();
                        jb.put(next.getKey(),next.getValue());
                    }
                }

                Integer width = rounding(String.valueOf(jb.get("width")));
                String widthPx = String.valueOf(jb.get("widthPx"));
                width = rounding(widthPx);

                Integer height = rounding(String.valueOf(jb.get("height")));
                String heightPx = String.valueOf(jb.get("heightPx"));
                height = rounding(heightPx);

                Integer type = Integer.valueOf(String.valueOf(jb.get("type")));

                Integer x = rounding(String.valueOf(jb.get("x")))+10;  //加10  画布的内边距
                String xPx = String.valueOf(jb.get("xPx"));
                x = rounding(xPx)+10;

                Integer y = rounding(String.valueOf(jb.get("y")))+10;  //加10  画布的内边距
                String yPx = String.valueOf(jb.get("yPx"));
                y = rounding(yPx)+10;

                String value = "";
                if(type==1){
                    value = String.valueOf(jb.get("value"));
                }

                if(type==2){
                    Object o2 = jb.get("value");
                    Map<String, Object> value1 = new HashMap<>();
                    if(o2 instanceof LinkedHashMap){
                        LinkedHashMap<String,Object> value2 = (LinkedHashMap) jb.get("value");
                        Set<Map.Entry<String, Object>> entries = value2.entrySet();
                        Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
                        while (iterator.hasNext()){
                            Map.Entry<String, Object> next = iterator.next();
                            value1.put(next.getKey(),next.getValue());
                        }
                    }
                    if(o2 instanceof JSONObject){
                        JSONObject value3 = (JSONObject) jb.get("value");
                        Set<Map.Entry<String, Object>> entries = value3.entrySet();
                        Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
                        while (iterator.hasNext()){
                            Map.Entry<String, Object> next = iterator.next();
                            value1.put(next.getKey(),next.getValue());
                        }
                    }

                    String label = String.valueOf(value1.get("label"));
                    String value2 = String.valueOf(value1.get("value"));
                    if(list!=null && list.size()!=0 && list.get(0)!=null){
                        String o = String.valueOf(list.get(0).get(value2.toUpperCase()));
                        value = o;
                    }else{
                        value = "["+label+"]";
                    }

                }
                headCells.add(new Cell(1, 1, width, 0).setContentAlign(contentAlign).setContent(value).setFontColor(color)
                        .setFontBold(fontbold).setHeight(height).setX(x).setY(y)); //设置字体颜色

            }
        }
        //表格内容填空
        List<List<String>> tableRowContents = new ArrayList<>();
        int[] mergeColumns = new int[]{1, 2};
        String guidang_position = sysConfigService.selectConfigByKey("SEAL_POSITION");
        if(StringUtils.isEmpty(guidang_position) || "null".equals(guidang_position)){
            throw new ServiceException("预览归档章文件路径未配置");
        }
        File file = new File(guidang_position);
        if(!file.exists()){
            file.mkdirs();
        }
        //生成图片路径
        Long userId = SecurityUtils.getUserId();
        String path = guidang_position+File.separator+"viewSeal"+("save".equals(isSave)?"_save":"")+"_"+userId+".png";

        /**
         * 字体字号 下面设置
         */
        Table table = new Table().setCellFont(new Font(font, Font.PLAIN, fontSize))
                .setHeadCells(headCells).setHeaderFont(new Font(font, Font.PLAIN, fontSize))
                .setHeaderBackGroundColor(Color.white).setRowHeight(rowHeight)
                .setMergeColumns(mergeColumns).setFontColor(color).setFontBold(fontbold);   //设置字体颜色以及粗细
        try {
            logger.info("=====预览生成图片开始=====");
            BufferedImage image = Cell.drawTable(table, tableRowContents);
            ImageIO.write(image, "png", new File(path));
            logger.info("=====预览生成图片结束=====");
            logger.info("=====预览生成图片路径：：：{}", path);
        }catch (Exception e){
            e.printStackTrace();
        }
        return path;
    }

    /**
     * 取整
     * @param num
     * @return
     */
    public int rounding(String num){
        double number = Double.parseDouble(num); // 先将字符串转换成double类型
        int roundedNumber = (int) Math.round(number);
        return roundedNumber;
    }
    @Override
    public String viewSeal(SealManage Sealmanage) {
        //String tableStyle = Sealmanage.getTableStyle();
        //JSONArray jsonArray = JSONArray.parseArray(tableStyle);
        Integer xPosition = Sealmanage.getxPosition();
        Integer yPosition = Sealmanage.getyPosition();
        Integer totalHeight = Sealmanage.getTotalHeight();
        Integer totalWidth = Sealmanage.getTotalWidth();
        totalHeight = Sealmanage.getTotalHeightPx();
        totalWidth = Sealmanage.getTotalWidthPx();
        String pageOfAdd = Sealmanage.getImagePath();
        //生成pdf路径
        String guidang_position = sysConfigService.selectConfigByKey("SEAL_POSITION");
        if(StringUtils.isEmpty(guidang_position) || "null".equals(guidang_position)){
            throw new ServiceException("预览归档章文件路径未配置");
        }
        File file = new File(guidang_position);
        if(!file.exists()){
            file.mkdirs();
        }
        Long userId = SecurityUtils.getUserId();
        String pdfPath = guidang_position+File.separator+"testpdfwater_"+userId+".pdf";
        try {
            /*logger.info("=====预览生成图片开始=====");
            BufferedImage image = Cell.drawTable(table, tableRowContents);
            ImageIO.write(image, "png", new File(path));
            logger.info("=====预览生成图片结束=====");
            logger.info("=====预览生成图片路径：：：{}",path);*/
            String imagePath = getImagePath(Sealmanage,null);
            logger.info("=====添加归档章开始=====");
            ClassPathResource classPathResource = new ClassPathResource("sealModel/testpdf.pdf");

            // 读取文件流
            InputStream inputStream = classPathResource.getInputStream();
            ByteArrayOutputStream qRcodePngStream = getQRcodePngStream(imagePath);
            byte[] data = qRcodePngStream.toByteArray();
            PdfUtil.addImage(inputStream, pdfPath, data,xPosition,yPosition,totalWidth,totalHeight,"0".equals(pageOfAdd)?true:false);
            logger.info("=====添加归档章结束=====");
            logger.info("=====添加归档章pdf路径：：：{}",pdfPath);
        } catch (IOException | DocumentException e) {
            e.printStackTrace();
        }
        return pdfPath;
    }

    public static ByteArrayOutputStream getQRcodePngStream(String path) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        FileImageInputStream input = null;
        try {
            input = new FileImageInputStream(new File(path));
            byte[] buf = new byte[1024];
            int numBytesRead = 0;
            while ((numBytesRead = input.read(buf)) != -1) {
                output.write(buf, 0, numBytesRead);
            }
        }catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                output.close();
                if(input!=null) input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return output;
    }
    /**
     * 新增归档章管理
     *
     * @param
     * @return 结果
     */
    @Override
    public int insertSealmanage(SealManage sealmanage)
    {
        Long categoryId = sealmanage.getCategoryId();
        SealManage sealManage = new SealManage();
        List<Map<String, Object>> maps = yqdaarticulatedMapper.executeSql("select id from " + sealManage.getTableName() + " " +
                "where "+(categoryId==null?"category_id is null":"category_id = "+categoryId+""));
        if(maps.size()!=0){
            throw new ServiceException("该门类已添加");
        }
        sealmanage.setCreateTime(DateUtils.getNowDate());
        sealmanage.setState("1"); //默认启用
        sealmanage.setCreateBy(SecurityUtils.getUsername());
        JSONArray tableStyleJson = sealmanage.getTableStyleJson();
        if(null!=tableStyleJson && tableStyleJson.size()!=0){
            sealmanage.setTableStyle(tableStyleJson.toJSONString());
        }
        return SealmanageMapper.insertSealmanage(sealmanage);
    }

    /**
     * 修改归档章管理
     *
     * @param sealmanage 归档章管理
     * @return 结果
     */
    @Override
    public int updateSealmanage(SealManage sealmanage)
    {
        Long categoryId = sealmanage.getCategoryId();
        Long id = sealmanage.getId();
        SealManage sealManage = new SealManage();
        SealManage sealManage1 = SealmanageMapper.selectSealmanageByID(String.valueOf(id), sealManage.getTableName());
        Long categoryId1 = sealManage1.getCategoryId();
        if(categoryId!=null){
            if(categoryId1.longValue()!=categoryId.longValue()){
                List<Map<String, Object>> maps = yqdaarticulatedMapper.executeSql("select id from " + sealManage.getTableName() + " " +
                        "where "+(categoryId==null?"category_id is null":"category_id = "+categoryId+""));
                if(maps.size()!=0){
                    throw new ServiceException("该门类已添加");
                }
            }
        }
        sealmanage.setUpdateTime(DateUtils.getNowDate());
        JSONArray tableStyleJson = sealmanage.getTableStyleJson();
        if(null!=tableStyleJson && tableStyleJson.size()!=0){
            sealmanage.setTableStyle(tableStyleJson.toJSONString());
        }
        return SealmanageMapper.updateSealmanage(sealmanage);
    }

    /**
     * 批量删除归档章管理
     *
     * @param IDs 需要删除的归档章管理主键
     * @return 结果
     */
    @Override
    public int deleteSealmanageByIDs(String[] IDs)
    {
        SealManage sealManage = new SealManage();
        return SealmanageMapper.deleteSealmanageByIDs(IDs,sealManage.getTableName());
    }

    /**
     * 删除归档章管理信息
     *
     * @param ID 归档章管理主键
     * @return 结果
     */
    @Override
    public int deleteSealmanageByID(String ID)
    {
        SealManage sealManage = new SealManage();
        return SealmanageMapper.deleteSealmanageByID(ID,sealManage.getTableName());
    }
}
